package cn.iocoder.yudao.module.iot.controller.app.scene;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.iot.controller.app.scene.vo.IotSceneCreateReqVO;
import cn.iocoder.yudao.module.iot.controller.app.scene.vo.IotSceneExecuteReqVO;
import cn.iocoder.yudao.module.iot.controller.app.scene.vo.IotSceneRespVO;
import cn.iocoder.yudao.module.iot.controller.app.scene.vo.IotSceneUpdateStatusReqVO;
import cn.iocoder.yudao.module.iot.controller.app.scene.vo.IotSceneUpdateReqVO;
import cn.iocoder.yudao.module.iot.controller.app.scene.vo.IotSceneTimerReqVO;
import cn.iocoder.yudao.module.iot.controller.app.scene.vo.IotSceneTimerRespVO;
import cn.iocoder.yudao.module.iot.service.scene.IotSceneService;
import cn.iocoder.yudao.module.iot.service.scene.IotSceneTimerService;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;

@Tag(name = "用户 APP - 场景管理")
@RestController
@RequestMapping("/iot/scene")
@Validated
@Slf4j
public class IotSceneController {

    @Resource
    private IotSceneService iotSceneService;

    @Resource
    private IotSceneTimerService iotSceneTimerService;

    @GetMapping("/test")
    public CommonResult<String> test() {
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 场景接口测试请求");
        return success("场景接口测试成功");
    }

    @GetMapping("/test-token")
    public CommonResult<String> testToken() {
        Long userId = getLoginUserId();
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] Token测试请求，userId: {}", userId);
        if (userId != null) {
            return success("Token验证成功，用户ID: " + userId);
        } else {
            return success("Token验证失败，无法获取用户ID");
        }
    }

    @PostMapping("/create")
    @Operation(summary = "创建场景", description = "创建场景信息")
    public CommonResult<Long> createScene(@RequestBody @Valid IotSceneCreateReqVO reqVO) {

        // 优先使用前端传递的userId，如果没有则从token中获取
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 创建场景请求，用户ID: {}, 参数: {}", userId, reqVO);
        
        Long id = iotSceneService.createScene(reqVO, userId);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 创建场景成功，场景ID: {}", id);
        return success(id);
    }

    @PostMapping("/update")
    @Operation(summary = "更新场景", description = "更新场景信息")
    public CommonResult<Boolean> updateScene(@RequestBody @Valid IotSceneUpdateReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 更新场景请求，用户ID: {}, 场景ID: {}, 参数: {}", userId, reqVO.getId(), reqVO);
        iotSceneService.updateScene(reqVO, userId);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 更新场景成功，场景ID: {}", reqVO.getId());
        return success(true);
    }

    @GetMapping("/list")
    public CommonResult<List<IotSceneRespVO>> getSceneList() {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 获取场景列表请求，userId: {}", userId);
        List<IotSceneRespVO> list = iotSceneService.getSceneList(userId);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 获取场景列表成功，数量: {}", list.size());
        return success(list);
    }

    @GetMapping("/get")
    public CommonResult<IotSceneRespVO> getScene(@RequestParam Long id) {
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 获取场景详情请求，场景ID: {}", id);
        IotSceneRespVO vo = iotSceneService.getSceneDetail(id);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 获取场景详情成功，场景ID: {}", id);
        return success(vo);
    }

    @PostMapping("/delete")
    @Operation(summary = "删除场景", description = "删除场景信息")
    public CommonResult<Boolean> deleteScene(@RequestParam Long id) {
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 删除场景请求，场景ID: {}", id);
        // 调用Service层，ServiceImpl已实现级联删除动作和条件
        iotSceneService.deleteScene(id);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 删除场景成功，场景ID: {}", id);
        return success(true);
    }

    @PostMapping("/execute")
    @Operation(summary = "执行场景", description = "执行场景")
    public CommonResult<Boolean> executeScene(@RequestBody @Valid IotSceneExecuteReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            log.warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 执行场景请求，场景ID: {}, userId: {}", reqVO.getId(), reqVO.getUserId());
        iotSceneService.executeScene(reqVO.getId(), userId);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 执行场景成功，场景ID: {}, userId: {}", reqVO.getId(), reqVO.getUserId());
        return success(true);
    }

    @PostMapping("/update-status")
    @Operation(summary = "更新场景状态", description = "更新场景状态")
    public CommonResult<Boolean> updateSceneStatus(@RequestBody @Valid IotSceneUpdateStatusReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 更新场景状态请求，用户ID: {}, 场景ID: {}, 状态: {}", userId, reqVO.getId(), reqVO.getStatus());
        iotSceneService.updateSceneStatus(reqVO.getId(), reqVO.getStatus(), userId);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 更新场景状态成功，场景ID: {}, 状态: {}", reqVO.getId(), reqVO.getStatus());
        return success(true);
    }

    // ==================== 定时任务相关接口 ====================

    @PostMapping("/timer/create")
    @Operation(summary = "创建定时器", description = "创建定时器")
    public CommonResult<Long> createSceneTimer(@RequestBody @Valid IotSceneTimerReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 创建场景定时任务请求，用户ID: {}, 场景ID: {}, 时间: {}", userId, reqVO.getSceneId(), reqVO.getTime());
        
        // 创建定时条件
        cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneConditionDO condition = 
            cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneConditionDO.builder()
                .sceneId(reqVO.getSceneId())
                .attr("定时")
                .value(reqVO.getTime())
                .operator("=")
                .build();
        
        Long jobId = iotSceneTimerService.createSceneTimer(reqVO.getSceneId(), condition);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 创建场景定时任务成功，场景ID: {}, 任务ID: {}", reqVO.getSceneId(), jobId);
        return success(jobId);
    }

    @PostMapping("/timer/update")
    @Operation(summary = "更新定时器", description = "更新定时器")
    public CommonResult<Boolean> updateSceneTimer(@RequestBody @Valid IotSceneTimerReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }

        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 更新场景定时任务请求，用户ID: {}, 场景ID: {}, 时间: {}", userId, reqVO.getSceneId(), reqVO.getTime());
        
        // 更新定时条件
        cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneConditionDO condition = 
            cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneConditionDO.builder()
                .sceneId(reqVO.getSceneId())
                .attr("定时")
                .value(reqVO.getTime())
                .operator("=")
                .build();
        
        iotSceneTimerService.updateSceneTimer(reqVO.getSceneId(), condition);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 更新场景定时任务成功，场景ID: {}", reqVO.getSceneId());
        return success(true);
    }

    @PostMapping("/timer/delete")
    @Operation(summary = "删除定时器", description = "删除定时器")
    public CommonResult<Boolean> deleteSceneTimer(@RequestParam Long sceneId) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 删除场景定时任务请求，用户ID: {}, 场景ID: {}", userId, sceneId);
        
        iotSceneTimerService.deleteSceneTimer(sceneId);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 删除场景定时任务成功，场景ID: {}", sceneId);
        return success(true);
    }

    @GetMapping("/timer/list")
    @Operation(summary = "获取定时器")
    public CommonResult<List<IotSceneTimerRespVO>> getSceneTimers(@RequestParam Long sceneId) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 获取场景定时任务列表请求，用户ID: {}, 场景ID: {}", userId, sceneId);
        
        List<cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneConditionDO> timerConditions = 
            iotSceneTimerService.getSceneTimerConditions(sceneId);
        
        List<IotSceneTimerRespVO> result = timerConditions.stream()
            .map(condition -> {
                IotSceneTimerRespVO respVO = new IotSceneTimerRespVO();
                respVO.setSceneId(condition.getSceneId());
                respVO.setTime(condition.getValue());
                respVO.setCronExpression(iotSceneTimerService.convertTimeToCron(condition.getValue()));
                respVO.setEnabled(true);
                return respVO;
            })
            .collect(java.util.stream.Collectors.toList());
        
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 获取场景定时任务列表成功，场景ID: {}, 数量: {}", sceneId, result.size());
        return success(result);
    }

    @PostMapping("/timer/sync")
    @Operation(summary = "同步场景定时任务请求", description = "同步场景定时任务请求")
    public CommonResult<Boolean> syncSceneTimer(@RequestParam Long sceneId) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();

        if (userId == null) {
            org.slf4j.LoggerFactory.getLogger(getClass()).warn("用户未登录，操作失败");
            return CommonResult.error(401, "用户未登录");
        }
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 同步场景定时任务请求，用户ID: {}, 场景ID: {}", userId, sceneId);
        
        iotSceneTimerService.syncSceneTimer(sceneId);
        org.slf4j.LoggerFactory.getLogger(getClass()).info("[IotSceneController] 同步场景定时任务成功，场景ID: {}", sceneId);
        return success(true);
    }
}